<template>
  <div class="works-content-box">
    <!-- form -->
    <div class="form-box">
      <t-input
        v-model="state.formData.name"
        class="form-input"
        :placeholder="$t('common.input.enterKeywordPlaceholder')"
        @change="onKeypressFun"
      >
        <template #prefix-icon>
          <img src="../../../assets/images/home/select.svg" />
        </template>
      </t-input>

      <!-- 批量操作控件 - 新增 -->
      <div class="batch-controls">
        <t-checkbox v-model="state.batchSelectMode" @change="toggleBatchSelectMode">
          {{ $t('common.videoList.batchSelect') }}
        </t-checkbox>

        <template v-if="state.batchSelectMode">
          <span class="selected-count" v-if="state.selectedVideos.length">
            {{ $t('common.videoList.selected') }}: {{ state.selectedVideos.length }}
          </span>

          <t-button
            size="small"
            theme="default"
            variant="outline"
            @click="selectAllInCurrentPage"
            v-if="hasMoreToSelectInCurrentPage"
          >
            {{ $t('common.videoList.selectAllInCurrentPage') }}
          </t-button>

          <t-button
            size="small"
            theme="danger"
            @click="batchDeleteVideos"
            v-if="state.selectedVideos.length"
          >
            {{ $t('common.videoList.batchDelete') }}
          </t-button>

          <t-dropdown
            v-if="hasSuccessfulSelectedVideos"
            trigger="click"
            :popup-props="{ overlayClassName: 'caption-dropdown' }"
          >
            <t-button size="small" theme="success">
              <template #icon><SubtitleIcon /></template>
              下载操作
            </t-button>
            <t-dropdown-menu>
              <t-dropdown-item @click="batchDownloadVideos(false)">
                <template #prefixIcon><DownloadIcon /></template>
                原视频
              </t-dropdown-item>
              <t-dropdown-item @click="batchDownloadVideos(true)">
                <template #prefixIcon><FileIcon /></template>
                字幕视频
              </t-dropdown-item>
            </t-dropdown-menu>
          </t-dropdown>

          <t-button
            size="small"
            theme="danger"
            @click="batchCaptionVideos"
            v-if="state.selectedVideos.length"
          >
            {{ $t('common.videoList.batchCaption') }}
          </t-button>

          <t-button
            size="small"
            theme="primary"
            @click="batchPrintedVideos"
            v-if="state.selectedVideos.length"
          >
            批量加印花
          </t-button>

          <t-button
            size="small"
            theme="default"
            variant="outline"
            @click="clearSelection"
            v-if="state.selectedVideos.length"
          >
            {{ $t('common.videoList.clearSelection') }}
          </t-button>
        </template>
      </div>
    </div>

    <div class="works-content-table">
      <div v-if="home.homeState.videoNum === 0" class="empty">
        <div class="empty-box">
          <img src="../../../assets/images/home/worksList.svg" />
          <div class="empty-text">{{ $t('common.videoList.emptyText') }}</div>
          <div class="empty-text">
            <span @click="linkRoute">{{ $t('common.videoList.emptyLinkRouteText') }}</span>
            {{ $t('common.videoList.emptyRightText') }}
          </div>
        </div>
      </div>
      <div v-else class="table-list">
        <div v-for="(item, index) in state.worksList" :key="index + 'worksList'"
             class="li"
             :class="{ 'selected-video': isVideoSelected(item.id) }"
             @click="state.batchSelectMode ? toggleSelectVideo(item) : null">

          <!-- 批量选择框 - 新增 -->
          <div v-if="state.batchSelectMode" class="batch-select-checkbox">
            <t-checkbox
              :checked="isVideoSelected(item.id)"
              @click.stop
              @change="(checked) => toggleSelectVideo(item, checked)"
            />
          </div>

          <!-- 视频上部分内容 -->
          <div class="img-video comme">
            <div class="img-video-content">
              <div v-if="item.status === 'success'" class="duration">
                {{ item.duration + '' ? millisecondsToTime(item.duration * 1000) : '00:00' }}
              </div>
              <div v-if="item.status === 'success'" class="works-video">
                <video :src="item.file_path"></video>
              </div>
              <img
                v-if="item.status === 'failed' || item.status === 'pending' || item.status === 'draft'"
                class="works-img"
                src="../../../assets/images/home/occupationMap.svg"
              />
              <div v-if="item.status === 'failed' || item.status === 'draft'" class="fail">
                <div class="fail-line"></div>
                <span>{{
                    item.status === 'failed'
                      ? $t('common.videoList.makeFailedText')
                      : $t('common.videoList.draftsText')
                  }}</span>
              </div>
            </div>
          </div>
          <!-- 下载和预览 -->
          <div
            class="download-preview comme"
            :style="
              item.status === 'failed' || item.status === 'success'
                ? 'background: rgba(0, 0, 0, 0.74);'
                : ''
            "
          >
            <div class="download-preview-content">
              <div
                v-if="item.status === 'success'"
                class="preview-button"
                @click.stop="previewVideo(item.file_path)"
              >
                <img src="../../../assets/images/home/video.svg" />
                <span>{{ $t('common.videoList.previewTitle') }}</span>
              </div>
              <div
                v-if="item.status === 'success' && item.with_caption === 1"
                class="preview-button"
                @click.stop="previewVideo(item.video_with_caption_path)"
              >
                <img src="../../../assets/images/home/video.svg" />
                <span>{{ $t('common.videoList.previewCaptionTitle') }}</span>
              </div>
              <div
                v-if="item.status === 'success'"
                class="download-button"
                @click.stop="downloadVideo(item, false)"
              >
                <div>
                  <img src="../../../assets/images/home/icon-down.svg" />
                  <span>{{ $t('common.videoList.downloadTitle') }}</span>
                </div>
              </div>
              <div
                v-if="item.status === 'success' && item.with_caption === 1"
                class="download-button2"
                @click.stop="downloadVideo(item, true)"
              >
                <div>
                  <img src="../../../assets/images/home/icon-down.svg" />
                  <span>{{ $t('common.videoList.downloadTitleCaption') }}</span>
                </div>
              </div>
              <div
                v-if="item.status === 'success' && item.caption_path"
                class="download-button-caption"
                @click.stop="previewCaption(item)"
              >
                <div>
                  <img src="../../../assets/images/home/caption.svg" />
                  <span>{{ $t('common.videoList.downloadCaptionTitle') }}</span>
                </div>
              </div>
              <div v-if="item.status === 'failed'" class="detection-failed-text">
                {{ $t('common.videoList.makeFailedText') }}
                <img src="../../../assets/images/home/icon-delete.svg" />
              </div>
              <div v-if="item.status === 'draft'" class="detection-failed-text">
                {{ $t('common.videoList.draftsText') }}
                <img src="../../../assets/images/home/icon-delete.svg" />
              </div>
              <div v-if="item.status === 'failed'" class="detection-failed-title">
                {{ item.message }}
              </div>
              <div
                v-if="
                  item.status === 'success' || item.status === 'failed' || item.status === 'draft'
                "
                class="delete-video"
                @click.stop="delVideo(item.id)"
              >
                <DeleteIcon style="color: #fff; font-size: 12px" />
              </div>
            </div>
          </div>
          <!-- 制作中 -->
          <div v-if="item.status === 'pending'" class="production comme">
            <div class="production-content">
              <img src="../../../assets/images/home/loading.svg" />
              <div class="progress-text">{{ item.progress }}%</div>
              <div class="production-text">{{ $t('common.videoList.underProduction') }}</div>
            </div>
            <div class="delete-video" @click.stop="delVideo(item.id)">
              <DeleteIcon style="color: #fff; font-size: 12px" />
            </div>
          </div>
          <!-- 排队中 -->
          <div v-if="item.status === 'waiting'" class="production comme">
            <div class="production-content">
              <img src="../../../assets/images/home/loading.svg" />
              <div class="progress-text">{{ item.progress }}</div>
              <div class="production-text">{{ $t('common.videoList.queuing') }}</div>
            </div>
            <div class="delete-video" @click.stop="delVideo(item.id)">
              <DeleteIcon style="color: #fff; font-size: 12px" />
            </div>
          </div>
          <!-- 视频下部分内容 -->
          <div class="bottom-text">
            <div class="h1">{{ item.name }}</div>
            <div class="text">
              {{ item.created_at ? formatDate(item.created_at) : '' }}
              <p style="float:right;color: red" v-if="item.with_caption === 0">未合并字幕</p>
              <p style="float:right;color: green" v-else>已合并字幕</p>
            </div>
          </div>
        </div>
      </div>
    </div>
    <div v-if="home.homeState.videoNum > 0" class="pagination-box">
      <div class="pagination-content">
        <t-config-provider :global-config="locale === 'zh' ? globalZh : globalEn">
          <t-pagination
            v-model="state.current"
            v-model:pageSize="state.pageSize"
            :total="state.total"
            show-jumper
            :page-size-options="[8, 16, 32, 48]"
            class="pagination"
            @page-size-change="onPageSizeChange"
            @current-change="onCurrentChange"
          />
        </t-config-provider>
      </div>
    </div>
    <VideoDialog
      :showVideoDialog="state.showVideoDialog"
      :videoUrl="state.videoUrl"
      @cancel="cancelFun"
    />
    <DeleteDialog ref="deleteDialogRef" @ok="okDelete" />

    <!-- 批量删除确认对话框 - 新增 -->
    <t-dialog
      v-model:visible="state.batchDeleteDialogVisible"
      :header="$t('common.videoList.batchDeleteConfirmTitle')"
      :confirm-btn="{
        content: $t('common.button.confirm'),
        theme: 'danger',
        loading: state.batchOperationLoading
      }"
      :cancel-btn="{ content: $t('common.button.cancel') }"
      @confirm="confirmBatchDelete"
    >
      <p>{{ $t('common.videoList.batchDeleteConfirmContent', { count: state.selectedVideos.length }) }}</p>
    </t-dialog>

    <!-- 批量下载进度对话框 - 新增 -->
    <t-dialog
      v-model:visible="state.batchDownloadDialogVisible"
      :header="$t('common.videoList.batchDownloadProgress')"
      :confirm-btn="null"
      :cancel-btn="null"
    >
      <div class="batch-download-progress">
        <t-progress
          :percentage="state.batchDownloadProgress"
          :label="true"
          :status="state.batchDownloadProgress === 100 ? 'success' : 'active'"
        />
        <div class="download-status">
          {{ $t('common.videoList.downloadingCount', { current: state.batchDownloadCurrent, total: state.batchDownloadTotal }) }}
        </div>
        <div class="download-actions">
          <t-button
            v-if="state.batchDownloadProgress === 100"
            theme="primary"
            @click="state.batchDownloadDialogVisible = false"
          >
            {{ $t('common.videoList.close') }}
          </t-button>
          <t-button
            v-else
            theme="danger"
            @click="cancelBatchDownload"
          >
            {{ $t('common.videoList.cancelDownload') }}
          </t-button>
        </div>
      </div>
    </t-dialog>

    <!-- 批量字幕压视频对话框 -->
    <t-dialog
      v-model:visible="state.batchCaptionDialogVisible"
      :header="$t('common.videoList.batchCaptionProgress')"
      :confirm-btn="null"
      :cancel-btn="null"
      :close-btn="false"
      width="500px"
    >
      <div class="batch-caption-progress">
        <!-- 简化的进度条，移除可能有问题的属性 -->
        <t-progress
          :percentage="state.batchCaptionProgress"
          :label="true"
        />

        <div class="progress-info">
          <div class="progress-status">
            <span class="current-count">{{ state.batchCaptionCurrent }}</span>
            <span class="separator">/</span>
            <span class="total-count">{{ state.batchCaptionTotal }}</span>
          </div>

          <div class="progress-text">
        <span v-if="state.batchCaptionProgress < 100 && !state.cancelBatchCaptionFlag">
          正在处理字幕压视频...
        </span>
            <span v-else-if="state.cancelBatchCaptionFlag">
          正在取消操作...
        </span>
            <span v-else>
          处理完成
        </span>
          </div>
        </div>

        <div class="progress-actions">
          <t-button
            v-if="state.batchCaptionProgress === 100 || state.cancelBatchCaptionFlag"
            theme="primary"
            @click="closeBatchCaptionDialog"
          >
            关闭
          </t-button>

          <t-button
            v-else
            theme="danger"
            @click="cancelBatchCaption"
            :disabled="state.cancelBatchCaptionFlag"
          >
            {{ state.cancelBatchCaptionFlag ? '取消中...' : '取消操作' }}
          </t-button>
        </div>
      </div>
    </t-dialog>

    <CaptionPreviewDialog
      v-model:visible="captionPreviewVisible"
      :captionPath="captionPreviewPath"
      :title="captionPreviewName"
    />
  </div>
</template>

<script setup>
import { reactive, onMounted, onBeforeUnmount, ref, computed } from 'vue'
import { DeleteIcon, DownloadIcon, FileIcon, SubtitleIcon } from 'tdesign-icons-vue-next'
import { videoPage, exportVideo, removeVideo, captionVideo, printedVideo } from '@renderer/api/index.js'
import { formatDate, millisecondsToTime } from '@renderer/utils/index.js'
import VideoDialog from '@renderer/views/home/components/videoDialog.vue'
import { Client } from '@renderer/client'
import { useHomeStore } from '@renderer/stores/home.js'
import { useRouter, useRoute } from 'vue-router'
import DeleteDialog from '@renderer/components/deleteDialog.vue'
import { MessagePlugin } from 'tdesign-vue-next'
import enConfig from 'tdesign-vue-next/es/locale/en_US'
import zhConfig from 'tdesign-vue-next/es/locale/zh_CN'
import { useI18n } from 'vue-i18n'
const { locale, t } = useI18n()
import { getBaseUrl } from '@renderer/api/assetPaths'

import merge from 'lodash/merge'
import CaptionPreviewDialog from '@renderer/views/audio/components/CaptionPreviewDialog.vue'
const globalEn = merge(enConfig, {
  pagination: {}
})
const globalZh = merge(zhConfig, {
  pagination: {}
})
const assetPaths = ref('')
const route = useRoute()
const router = useRouter()
const captionPreviewVisible = ref(false)
const home = useHomeStore()
const deleteDialogRef = ref(null)
const captionPreviewPath = ref('')
const captionPreviewName = ref('')
const state = reactive({
  interval: null,
  current: 1,
  videoUrl: '',
  showVideoDialog: false,
  pageSize: 8,
  total: 0,
  delVideoId: '',
  worksList: [],
  url: `file:///B:/dd.mov`,
  formData: {
    name: ''
  },

  // 批量操作相关 - 新增
  batchSelectMode: false,
  selectedVideos: [],
  batchDeleteDialogVisible: false,

  // 批量下载相关 - 新增
  batchDownloadDialogVisible: false,
  batchDownloadProgress: 0,
  batchDownloadTotal: 0,
  batchDownloadCurrent: 0,
  batchOperationLoading: false,
  cancelBatchDownloadFlag: false,

  // 批量压字幕相关 - 新增
  batchCaptionDialogVisible: false,
  batchCaptionProgress: 0,
  batchCaptionTotal: 0,
  batchCaptionCurrent: 0,
  cancelBatchCaptionFlag: false,

})

// 判断是否有可选择的视频 - 新增
const hasMoreToSelectInCurrentPage = computed(() => {
  // 检查当前页面是否有未选中的视频
  return state.worksList.some(video => !isVideoSelected(video.id));
});

// 判断是否有成功状态的已选视频 - 新增
const hasSuccessfulSelectedVideos = computed(() => {
  // 检查选中的视频中是否有状态为success的
  return state.selectedVideos.some(videoId => {
    const video = state.worksList.find(v => v.id === videoId);
    return video && video.status === 'success';
  });
});

onMounted(async () => {
  await getBaseUrl().then((result) => {
    assetPaths.value = result
  })


  await videoPageAJax()
  state.interval = setInterval(() => {
    videoPageAJax()
  }, 3000)
})

onBeforeUnmount(() => {
  clearInterval(state.interval)
})

const cancelFun = () => {
  state.showVideoDialog = false
}

const linkRoute = () => {
  router.push('/video/edit')
}

const previewVideo = (url) => {
  state.showVideoDialog = true
  state.videoUrl = url
}

const videoPageAJax = async () => {
  try {
    const res = await videoPage({
      page: state.current,
      pageSize: state.pageSize,
      name: state.formData.name
    })
    if (res) {
      const { total, list } = res
      if (list) {
        state.total = total
        state.worksList = list
      }
    }
  } catch (error) {
    console.log(error)
  }
}

const onKeypressFun = () => {
  if (!state.isTime) {
    state.isTime = true
    const timeout = setTimeout(() => {
      videoPageAJax()
      state.isTime = false
      clearTimeout(timeout)
    }, 800)
  }
}

const onPageSizeChange = (size) => {
  state.pageSize = size
  videoPageAJax()
}

const onCurrentChange = (index) => {
  state.page = index
  videoPageAJax()
}

const delVideo = (id) => {
  console.log("🚀 ~ delVideo ~ id:", id)
  if (deleteDialogRef.value && deleteDialogRef.value.showDialogFun) {
    deleteDialogRef.value.showDialogFun()
    state.delVideoId = id
  }
}

const okDelete = () => {
  removeVideo(state.delVideoId)
    .then(() => {
      videoPageAJax()
      MessagePlugin.success(t('common.message.deleteSuccessText'))
      home.setVideoNum(home.homeState.videoNum > 0 ? home.homeState.videoNum - 1 : 0)

      // 从选中列表中移除已删除的视频 - 新增
      if (state.selectedVideos.includes(state.delVideoId)) {
        state.selectedVideos = state.selectedVideos.filter(id => id !== state.delVideoId);
      }
    })
    .catch((error) => {
      MessagePlugin.error(t('common.message.deleteErrorText'))
      console.error('Error:', error)
    })
}

const downloadVideo = async (video, is_caption) => {
  const fileExtension = video.file_path?.split('.')?.pop()
  const saveName = `${video.name}.${fileExtension}`
  // exportVideo
  try {
    const savePath = await Client.file.saveFile(saveName)
    if (!savePath) return;

    try {
      const res = await exportVideo(video.id, savePath, is_caption)
      await MessagePlugin.success(t('common.videoList.downloadStarted'))
    } catch (error) {
      console.log(error)
      await MessagePlugin.error(t('common.videoList.downloadFailed'))
    }
  } catch (error) {
    console.log(error)
  }
}

// 切换批量选择模式
const toggleBatchSelectMode = (checked) => {
  state.batchSelectMode = checked;
  if (!checked) {
    // 退出批量选择模式时清空选择
    state.selectedVideos = [];
  }
};

// 检查视频是否被选中
const isVideoSelected = (videoId) => {
  return state.selectedVideos.includes(videoId);
};

// 切换选择视频
const toggleSelectVideo = (video, checked = null) => {
  const videoId = video.id;

  // 如果传入了明确的checked值，就使用它，否则根据当前状态切换
  if (checked !== null) {
    if (checked && !isVideoSelected(videoId)) {
      state.selectedVideos.push(videoId);
    } else if (!checked && isVideoSelected(videoId)) {
      state.selectedVideos = state.selectedVideos.filter(id => id !== videoId);
    }
  } else {
    // 切换选中状态
    if (isVideoSelected(videoId)) {
      state.selectedVideos = state.selectedVideos.filter(id => id !== videoId);
    } else {
      state.selectedVideos.push(videoId);
    }
  }
};

// 选择当前页面上的所有视频
const selectAllInCurrentPage = () => {
  const currentPageIds = state.worksList.map(video => video.id);

  // 合并当前选择和当前页面ID，避免重复
  const newSelection = [...state.selectedVideos];

  currentPageIds.forEach(id => {
    if (!newSelection.includes(id)) {
      newSelection.push(id);
    }
  });

  state.selectedVideos = newSelection;
  MessagePlugin.success(t('common.videoList.selectAllSuccess'));
};

// 清空选择
const clearSelection = () => {
  state.selectedVideos = [];
  MessagePlugin.success(t('common.videoList.clearSelectionSuccess'));
};

// 编辑字幕
const previewCaption = (item) => {
  if (!item.id || !item.caption_path) {
    MessagePlugin.warning('字幕不可用')
    return
  }

  captionPreviewPath.value = item.caption_path
  captionPreviewName.value = item.name || '未命名'
  captionPreviewVisible.value = true
};

// 批量删除视频
const batchDeleteVideos = () => {
  if (state.selectedVideos.length === 0) {
    MessagePlugin.warning(t('common.videoList.noVideoSelected'));
    return;
  }

  // 显示确认对话框
  state.batchDeleteDialogVisible = true;
};

// 确认批量删除
const confirmBatchDelete = async () => {
  if (state.selectedVideos.length === 0) {
    state.batchDeleteDialogVisible = false;
    return;
  }

  state.batchOperationLoading = true;

  try {
    // 记录删除前的视频数量
    const videosToDelete = [...state.selectedVideos];
    const deleteCount = videosToDelete.length;
    let successCount = 0;

    // 依次删除所有选中的视频
    for (const videoId of videosToDelete) {
      try {
        await removeVideo(videoId);
        successCount++;

        // 从选中列表中移除
        state.selectedVideos = state.selectedVideos.filter(id => id !== videoId);
      } catch (error) {
        console.error(`删除视频失败 (ID: ${videoId}):`, error);
      }
    }

    // 刷新视频列表
    await videoPageAJax();

    // 更新视频总数
    home.setVideoNum(home.homeState.videoNum - successCount);

    await MessagePlugin.success(t('common.videoList.batchDeleteSuccess', { count: successCount }));
  } catch (error) {
    console.error('批量删除失败:', error);
    await MessagePlugin.error(t('common.videoList.batchDeleteFailed'));
  } finally {
    state.batchOperationLoading = false;
    state.batchDeleteDialogVisible = false;
  }
};

// 批量压字幕
const batchCaptionVideos = async () => {
  if (state.selectedVideos.length === 0) {
    await MessagePlugin.warning(t('common.videoList.noVideoSelected'));
    return;
  }

  // 先显示进度对话框，使用选中的视频总数作为初始总数
  state.batchCaptionDialogVisible = true;
  state.batchCaptionTotal = state.selectedVideos.length; // 使用选中的总数
  state.batchCaptionCurrent = 0;
  state.batchCaptionProgress = 0;
  state.cancelBatchCaptionFlag = false;
  state.batchOperationLoading = true;

  try {
    // 保存当前页码和页大小，稍后恢复
    const currentPage = state.current;
    const currentPageSize = state.pageSize;

    // 先获取当前页面中的选中成功视频
    let successVideos = state.worksList.filter(video =>
      state.selectedVideos.includes(video.id) && video.status === 'success'
    );

    // 检查是否有不在当前页面的视频需要获取
    const currentPageVideoIds = state.worksList.map(video => video.id);
    const nonCurrentPageVideoIds = state.selectedVideos.filter(
      id => !currentPageVideoIds.includes(id)
    );

    if (nonCurrentPageVideoIds.length > 0) {
      // 计算需要查询的页数
      const totalPages = Math.ceil(state.total / state.pageSize);

      // 保存当前的视频列表
      const originalWorksList = [...state.worksList];

      // 逐页获取视频数据，查找选中的视频
      for (let page = 1; page <= totalPages; page++) {
        if (page === currentPage) continue; // 跳过当前页，因为已经处理过了

        // 请求其他页数据
        const tempResult = await videoPage({
          page: page,
          pageSize: currentPageSize,
          name: state.formData.name
        });

        if (tempResult && tempResult.list) {
          // 从返回的列表中找出选中的且状态为success的视频
          const pageSuccessVideos = tempResult.list.filter(video =>
            state.selectedVideos.includes(video.id) && video.status === 'success'
          );

          // 添加到成功视频列表
          successVideos = [...successVideos, ...pageSuccessVideos];
        }
      }

      // 恢复原始视频列表（不改变当前页面显示）
      state.worksList = originalWorksList;

      // 恢复原始页码
      await videoPage({
        page: currentPage,
        pageSize: currentPageSize,
        name: state.formData.name
      });
    }

    if (successVideos.length === 0) {
      await MessagePlugin.warning(t('common.videoList.noSuccessfulVideoSelected'));
      state.batchCaptionDialogVisible = false;
      state.batchOperationLoading = false;
      return;
    }

    // 统计处理结果
    let successCount = 0;
    let failureCount = 0;
    const failedVideos = [];

    // 逐个处理视频
    for (let i = 0; i < successVideos.length; i++) {
      // 检查是否取消处理
      if (state.cancelBatchCaptionFlag) {
        await MessagePlugin.info(t('common.videoList.CaptionCancelled'));
        break;
      }

      const video = successVideos[i];

      try {
        // 参数验证
        const params = {
          id: video.id,
          file_path: transformFilePaths(video.file_path),
          caption_path: video.caption_path,
          output_path: transformOutputPaths(video.file_path)
        };

        // 检查参数有效性
        if (!params.caption_path || params.caption_path.trim() === '') {
          throw new Error('字幕文件路径为空');
        }

        if (!params.file_path || params.file_path.trim() === '') {
          throw new Error('视频文件路径为空');
        }

        if (!params.output_path || params.output_path.trim() === '') {
          throw new Error('输出路径为空');
        }

        await captionVideo(
          params.id,
          params.file_path,
          params.caption_path,
          params.output_path
        );

        successCount++;
        console.log(`视频 ${video.id} 处理成功`);

      } catch (error) {
        failureCount++;
        const errorMessage = error.message || '未知错误';
        console.error(`字幕压视频失败 (ID: ${video.id}):`, errorMessage);

        failedVideos.push({
          id: video.id,
          name: video.name || `视频 ${video.id}`,
          error: errorMessage
        });

      }

      state.batchCaptionCurrent++;
      state.batchCaptionProgress = Math.floor((state.batchCaptionCurrent / state.batchCaptionTotal) * 100);

    }

    // 显示最终结果
    if (!state.cancelBatchCaptionFlag) {
      const totalSelected = state.selectedVideos.length;
      const totalProcessed = successCount + failureCount;
      const totalSkipped = totalSelected - totalProcessed;

      if (failureCount === 0 && totalSkipped === 0) {
        // 全部成功
        await MessagePlugin.success(
          t('common.videoList.batchCaptionComplete', { count: successCount })
        );
      } else if (successCount === 0) {
        // 全部失败或跳过
        if (totalSkipped > 0) {
          await MessagePlugin.warning(
            `所选 ${totalSelected} 个视频中，${totalSkipped} 个被跳过（状态非success），${failureCount} 个处理失败`
          );
        } else {
          await MessagePlugin.error(
            t('common.videoList.batchCaptionAllFailed', { count: failureCount })
          );
        }
      } else {
        // 部分成功
        let message = `批量处理完成：成功 ${successCount} 个`;
        if (failureCount > 0) {
          message += `，失败 ${failureCount} 个`;
        }
        if (totalSkipped > 0) {
          message += `，跳过 ${totalSkipped} 个`;
        }
        message += `，共选中 ${totalSelected} 个`;

        await MessagePlugin.warning(message);
      }
    }

  } catch (error) {
    console.error('批量字幕压视频失败:', error);
    await MessagePlugin.error(t('common.videoList.batchCaptionFailed'));
  } finally {
    state.batchOperationLoading = false;

    // 延迟关闭对话框，让用户看到最终进度
    if (state.batchCaptionProgress === 100 || state.cancelBatchCaptionFlag) {
      setTimeout(() => {
        state.batchCaptionDialogVisible = false;
        // 重置状态
        state.batchCaptionTotal = 0;
        state.batchCaptionCurrent = 0;
        state.batchCaptionProgress = 0;
        state.cancelBatchCaptionFlag = false;
      }, 2000); // 增加延迟时间让用户看到结果
    }
  }
};

// 批量加印花
const batchPrintedVideos = async () => {
  if (state.selectedVideos.length === 0) {
    await MessagePlugin.warning(t('common.videoList.noVideoSelected'));
    return;
  }

  try {
    // 保存当前页码和页大小，稍后恢复
    const currentPage = state.current;
    const currentPageSize = state.pageSize;

    // 先获取当前页面中的选中成功视频
    let successVideos = state.worksList.filter(video =>
      state.selectedVideos.includes(video.id) && video.status === 'success'
    );

    // 检查是否有不在当前页面的视频需要获取
    const currentPageVideoIds = state.worksList.map(video => video.id);
    const nonCurrentPageVideoIds = state.selectedVideos.filter(
      id => !currentPageVideoIds.includes(id)
    );

    if (nonCurrentPageVideoIds.length > 0) {
      // 计算需要查询的页数
      const totalPages = Math.ceil(state.total / state.pageSize);

      // 保存当前的视频列表
      const originalWorksList = [...state.worksList];

      // 逐页获取视频数据，查找选中的视频
      for (let page = 1; page <= totalPages; page++) {
        if (page === currentPage) continue; // 跳过当前页，因为已经处理过了

        // 请求其他页数据
        const tempResult = await videoPage({
          page: page,
          pageSize: currentPageSize,
          name: state.formData.name
        });

        if (tempResult && tempResult.list) {
          // 从返回的列表中找出选中的且状态为success的视频
          const pageSuccessVideos = tempResult.list.filter(video =>
            state.selectedVideos.includes(video.id) && video.status === 'success'
          );

          // 添加到成功视频列表
          successVideos = [...successVideos, ...pageSuccessVideos];
        }
      }

      // 恢复原始视频列表（不改变当前页面显示）
      state.worksList = originalWorksList;

      // 恢复原始页码
      await videoPage({
        page: currentPage,
        pageSize: currentPageSize,
        name: state.formData.name
      });
    }

    if (successVideos.length === 0) {
      await MessagePlugin.warning(t('common.videoList.noSuccessfulVideoSelected'));
      state.batchCaptionDialogVisible = false;
      state.batchOperationLoading = false;
      return;
    }

    console.log('原始成功视频数据:', JSON.stringify(successVideos));

    // 路径转换方法
    const convertSubtitlePath = (originalPath) => {
      // 从原始路径中提取文件名
      const fileName = originalPath.split('\\').pop() || originalPath.split('/').pop();
      // 构造新的字幕路径
      return `D:\\Deploy\\video_classifier_frontend\\public\\subtitles\\${fileName}`;
    };

    const convertVideoPath = (originalPath) => {
      // 从原始路径中提取文件名
      const fileName = originalPath.split('\\').pop() || originalPath.split('/').pop();
      // 构造新的视频路径
      return `D:\\heygem_data\\face2face\\temp\\with_caption\\${fileName}`;
    };

    // 按字幕路径分组视频
    const captionGroups = {};

    successVideos.forEach(video => {
      // 检查必要字段是否存在
      if (!video.caption_path || !video.video_with_caption_path) {
        console.warn('视频缺少必要字段:', video.id, video.name);
        return;
      }

      // 转换路径
      const convertedCaptionPath = convertSubtitlePath(video.caption_path);
      const convertedVideoPath = convertVideoPath(video.video_with_caption_path);

      if (!captionGroups[convertedCaptionPath]) {
        captionGroups[convertedCaptionPath] = [];
      }

      captionGroups[convertedCaptionPath].push(convertedVideoPath);
    });

    // 构建服务器需要的数据格式
    const printedData = {
      mappings: Object.entries(captionGroups).map(([convertedCaptionPath, convertedVideoPaths]) => ({
        video_paths: convertedVideoPaths,
        subtitle_path: convertedCaptionPath,
        updated_at: Date.now()
      }))
    };

    // 检查是否有数据可以处理
    if (printedData.mappings.length === 0) {
      await MessagePlugin.warning('没有找到可处理的视频数据（缺少字幕路径或视频路径）');
      return;
    }

    const result = await printedVideo(printedData)
    if (result) {
      setTimeout(async () => {
        // 跳转到混剪页面
        await router.push({
          name: 'kpop',
          query: {
            ...route.query,
            src: `${assetPaths.value}:5173/football`,
          }
        })
      },2000)
    } else {
      await MessagePlugin.error('批量加印花处理失败');
    }

  } catch (error) {
    console.error('批量加印花失败:', error);
    await MessagePlugin.error(t('common.videoList.batchCaptionFailed'));
  }
}

// 批量下载视频
const batchDownloadVideos = async (is_caption) => {
  if (state.selectedVideos.length === 0) {
    await MessagePlugin.warning(t('common.videoList.noVideoSelected'));
    return;
  }

  state.batchOperationLoading = true;

  try {
    // 保存当前页码和页大小，稍后恢复
    const currentPage = state.current;
    const currentPageSize = state.pageSize;

    // 先获取当前页面中的选中成功视频
    let successVideos = state.worksList.filter(video =>
      state.selectedVideos.includes(video.id) && video.status === 'success'
    );

    // 检查是否有不在当前页面的视频需要获取
    const currentPageVideoIds = state.worksList.map(video => video.id);
    const nonCurrentPageVideoIds = state.selectedVideos.filter(
      id => !currentPageVideoIds.includes(id)
    );

    if (nonCurrentPageVideoIds.length > 0) {
      // 计算需要查询的页数
      const totalPages = Math.ceil(state.total / state.pageSize);

      // 保存当前的视频列表
      const originalWorksList = [...state.worksList];

      // 逐页获取视频数据，查找选中的视频
      for (let page = 1; page <= totalPages; page++) {
        if (page === currentPage) continue; // 跳过当前页，因为已经处理过了

        // 请求其他页数据
        const tempResult = await videoPage({
          page: page,
          pageSize: currentPageSize,
          name: state.formData.name
        });

        if (tempResult && tempResult.list) {
          // 从返回的列表中找出选中的且状态为success的视频
          const pageSuccessVideos = tempResult.list.filter(video =>
            state.selectedVideos.includes(video.id) && video.status === 'success'
          );

          // 添加到成功视频列表
          successVideos = [...successVideos, ...pageSuccessVideos];
        }
      }

      // 恢复原始视频列表（不改变当前页面显示）
      state.worksList = originalWorksList;

      // 恢复原始页码
      await videoPage({
        page: currentPage,
        pageSize: currentPageSize,
        name: state.formData.name
      });
    }

    if (successVideos.length === 0) {
      await MessagePlugin.warning(t('common.videoList.noSuccessfulVideoSelected'));
      state.batchOperationLoading = false;
      return;
    }

    // 选择保存目录
    const saveDirectory = await selectDirectory();
    if (!saveDirectory) {
      state.batchOperationLoading = false;
      return; // 用户取消选择
    }

    // 设置批量下载状态
    state.batchDownloadDialogVisible = true;
    state.batchDownloadTotal = successVideos.length;
    state.batchDownloadCurrent = 0;
    state.batchDownloadProgress = 0;
    state.cancelBatchDownloadFlag = false;

    // 逐个下载视频
    for (let i = 0; i < successVideos.length; i++) {
      // 检查是否取消下载
      if (state.cancelBatchDownloadFlag) {
        await MessagePlugin.info(t('common.videoList.downloadCancelled'));
        break;
      }

      const video = successVideos[i];
      const fileExtension = video.file_path?.split('.')?.pop();
      const savePath = `${saveDirectory}/${video.name}.${fileExtension}`;

      try {
        await exportVideo(video.id, savePath, is_caption);
        state.batchDownloadCurrent++;
        state.batchDownloadProgress = Math.floor((state.batchDownloadCurrent / state.batchDownloadTotal) * 100);
      } catch (error) {
        console.error(`下载视频失败 (ID: ${video.id}):`, error);
      }
    }

    if (state.batchDownloadCurrent > 0 && !state.cancelBatchDownloadFlag) {
      await MessagePlugin.success(t('common.videoList.batchDownloadComplete', { count: state.batchDownloadCurrent }));
    }
  } catch (error) {
    console.error('批量下载失败:', error);
    await MessagePlugin.error(t('common.videoList.batchDownloadFailed'));
  } finally {
    state.batchOperationLoading = false;
    if (state.batchDownloadProgress === 100 || state.cancelBatchDownloadFlag) {
      // 下载完成或被取消时关闭对话框
      setTimeout(() => {
        state.batchDownloadDialogVisible = false;
      }, 1000);
    }
  }
};

// 取消批量下载
const cancelBatchDownload = () => {
  state.cancelBatchDownloadFlag = true;
};

const closeBatchCaptionDialog = () => {
  state.batchCaptionDialogVisible = false;
  // 重置状态
  state.batchCaptionTotal = 0;
  state.batchCaptionCurrent = 0;
  state.batchCaptionProgress = 0;
  state.cancelBatchCaptionFlag = false;
};

// 取消批量字幕压视频
const cancelBatchCaption = () => {
  if (!state.cancelBatchCaptionFlag) {
    state.cancelBatchCaptionFlag = true;
    console.log('用户取消批量字幕压视频操作');
  }
};

// 选择目录函数
const selectDirectory = async () => {
  try {
    const result = await Client.file.selectDirectory();

    if (!result.canceled && result.filePaths.length > 0) {
      return result.filePaths[0];
    }
    return null;
  } catch (error) {
    console.error('选择目录失败:', error);
    return null;
  }
};

function transformFilePaths(file_path) {
  // 转换 file_path
  const filePathRegex = /^http:\/\/192\.168\.0\.152:9001\/(.*)$/;

  // 检查是否匹配，匹配后替换路径
  if (file_path.match(filePathRegex)) {
    const relativePath = file_path.replace(filePathRegex, '$1');
    file_path = '\\\\192.168.0.152\\d\\heygem_data\\' + relativePath.replace(/\//g, '\\');
  }

  return file_path;
}

function transformOutputPaths(output_path) {
  // 先替换掉 URL 协议部分
  const outputFileRegex = /^http:\/\/192\.168\.0\.152:9001\/(.*)$/;
  if (output_path.match(outputFileRegex)) {
    const relativePath = output_path.replace(outputFileRegex, '$1');
    output_path = '\\\\192.168.0.152\\d\\heygem_data\\' + relativePath.replace(/\//g, '\\');
  }

  // 修改 output_path 生成新的路径，包含 with_caption 目录
  const outputFileNameRegex = /^(.*)\\(.*)$/;
  if (output_path.match(outputFileNameRegex)) {
    const basePath = output_path.replace(outputFileNameRegex, '$1');
    const fileName = output_path.replace(outputFileNameRegex, '$2');
    output_path = `${basePath}\\with_caption\\${fileName.replace('.mp4', '_with_caption.mp4')}`;
  }

  return output_path;
}

</script>

<style lang="less" scoped>
.batch-caption-progress {
  padding: 20px 0;
}

.progress-info {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin: 16px 0;
  font-size: 14px;
}

.progress-status {
  font-weight: 500;
  color: #333;
}

.current-count {
  color: #0052d9;
  font-weight: 600;
}

.separator {
  margin: 0 4px;
  color: #999;
}

.total-count {
  color: #666;
}

.progress-text {
  color: #666;
}

.progress-actions {
  margin-top: 20px;
  text-align: center;
}

.debug-info {
  padding: 8px;
  background: #f5f5f5;
  border-radius: 4px;
  font-family: monospace;
}

.works-content-box {
  .form-box {
    display: flex;
    margin-bottom: 24px;
    position: absolute;
    top: -50px;
    right: 0;

    .form-input {
      width: 216px;
      margin-left: auto;
    }

    /* 批量操作控件 - 新增 */
    .batch-controls {
      display: flex;
      align-items: center;
      gap: 10px;
      margin-left: 15px;

      .selected-count {
        font-size: 12px;
        color: #666;
        margin: 0 5px;
      }
    }
  }

  .works-content-table {
    min-height: calc(100vh - 384px);
    .empty {
      display: flex;
      justify-content: center;
      align-items: center;
      height: calc(100vh - 414px);
      .empty-box {
        img {
          width: 160px;
          display: block;
          margin: 0 auto;
        }
        .empty-text {
          font-family: PingFang SC, PingFang SC;
          font-weight: 400;
          font-size: 12px;
          text-align: center;
          color: #999999;
          line-height: 16px;
          span {
            color: #434af9;
            border-bottom: 1xp solid #434af9;
            cursor: pointer;
          }
        }
      }
    }
    .table-list {
      display: grid;
      padding-bottom: 40px;
      grid-template-columns: repeat(5, 1fr);
      gap: 16px;
      color: #ccc;

      .li:hover {
        transform: scale(1.01);
        box-shadow: 0px 0px 12px rgba(0, 0, 0, 0.12);

        .download-preview {
          z-index: 2;
          display: flex;
          justify-content: center;
          align-items: center;
          position: relative;

          .download-preview-content {
            .download-button {
              width: 90px;
              height: 30px;
              cursor: pointer;
              background: green;
              border: 1px solid green;
              border-radius: 4px;
              display: flex;
              align-items: center;
              justify-content: center;
              font-family: PingFang SC, PingFang SC;
              font-weight: 500;
              font-size: 12px;
              color: #ffffff;

              line-height: 18px;

              img {
                margin-right: 4px;
              }
            }

            .download-button2 {
              width: 90px;
              height: 30px;
              cursor: pointer;
              background: green;
              border: 1px solid green;
              border-radius: 4px;
              display: flex;
              margin-top: 8px;
              align-items: center;
              justify-content: center;
              font-family: PingFang SC, PingFang SC;
              font-weight: 500;
              font-size: 12px;
              color: #ffffff;

              line-height: 18px;

              img {
                margin-right: 4px;
              }
            }

            .download-button-caption{
              width: 90px;
              height: 30px;
              cursor: pointer;
              background: #434af9;
              border: 1px solid #434af9;
              display: flex;
              align-items: center;
              justify-content: center;
              margin-top: 8px;
              border-radius: 4px;
              font-family: PingFang SC, PingFang SC;
              font-weight: 500;
              font-size: 12px;
              color: #ffffff;
              line-height: 18px;

              img {
                margin-right: 4px;
              }
            }

            .detection-failed-text {
              font-family: PingFang SC, PingFang SC;
              font-weight: 500;
              font-size: 12px;
              padding: 0 6px;
              display: flex;
              justify-content: center;
              color: #ffffff;
              line-height: 18px;
              margin-bottom: 12px;
            }

            .detection-failed-title {
              font-family: PingFang SC, PingFang SC;
              font-weight: 400;
              width: 80px;
              text-align: center;
              font-size: 12px;
              display: flex;
              justify-content: center;
              color: #ffffff;
              line-height: 18px;
            }

            .preview-button {
              width: 90px;
              height: 30px;
              cursor: pointer;
              display: flex;
              align-items: center;
              justify-content: center;
              margin-bottom: 8px;
              border-radius: 4px;
              font-family: PingFang SC, PingFang SC;
              font-weight: 500;
              font-size: 12px;
              color: #ffffff;
              line-height: 18px;
              border: 1px solid rgba(255, 255, 255, 0.6);

              img {
                margin-right: 4px;
              }
            }
          }
        }
      }

      .delete-video {
        width: 20px;
        height: 20px;
        background: rgba(255, 255, 255, 0.2);
        border-radius: 6px;
        position: absolute;
        left: 10px;
        display: flex;
        align-items: center;
        justify-content: center;
        cursor: pointer;
        top: 10px;
      }

      .li {
        transition: all 0.3s ease;
        aspect-ratio: 1 / 1.6;
        border-radius: 8px;
        position: relative;

        /* 选中状态 - 新增 */
        &.selected-video {
          &::after {
            content: '';
            position: absolute;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            border: 2px solid #434af9;
            border-radius: 8px;
            pointer-events: none;
            z-index: 5;
          }
        }

        /* 批量选择框 - 新增 */
        .batch-select-checkbox {
          position: absolute;
          top: 10px;
          right: 10px;
          z-index: 10;
          background: rgba(0, 0, 0, 0.5);
          border-radius: 4px;
          padding: 3px;
          width: 20px;
          height: 20px;
          display: flex;
          align-items: center;
          justify-content: center;

          :deep(.t-checkbox__input) {
            //background-color: white;
          }

          :deep(.t-checkbox__label) {
            display: none;
          }
        }

        .download-preview {
          display: none;
        }

        .comme {
          position: absolute;
          top: 0;
          width: 100%;
          left: 0;
          border-radius: 8px 8px 0 0;
          height: calc(100% - 64px);
        }

        .img-video {
          z-index: 1;

          .img-video-content {
            position: relative;
            height: 100%;
            background-color: #ebeef5;
            border-radius: 10px 10px 0 0;
            overflow: hidden;

            .works-img {
              width: 100%;
              border-radius: 8px 8px 0 0;
              background-color: #fff;
            }

            .works-video {
              width: 100%;
              height: 100%;
              overflow: hidden;
              position: absolute;
              border-radius: 8px 8px 0 0;
              left: 0;
              display: flex;
              align-items: center;
              top: 0;
              video {
                width: 100%;
              }
            }

            .fail {
              padding: 0 6px;
              height: 22px;
              background: rgba(255, 255, 255, 0.9);
              border-radius: 0px 8px 0px 8px;
              position: absolute;
              display: flex;
              justify-content: center;
              align-items: center;
              top: 0;
              right: 0;

              .fail-line {
                width: 4px;
                height: 4px;
                background: #ff2f2f;
                border-radius: 8px;
                margin-right: 5px;
              }

              span {
                font-family: HarmonyOS Sans SC, HarmonyOS Sans SC;
                font-weight: 400;
                font-size: 12px;
                color: #253858;
                line-height: 14px;
              }
            }

            .duration {
              padding: 0 5px;
              position: absolute;
              bottom: 8px;
              right: 8px;
              height: 18px;
              background: rgba(0, 0, 0, 0.63);
              border-radius: 4px;
              font-family: PingFang SC, PingFang SC;
              font-weight: 400;
              display: flex;
              justify-content: center;
              align-items: center;
              font-size: 10px;
              color: #ffffff;
              line-height: 12px;
              font-style: normal;
            }
          }
        }

        .bottom-text {
          height: 64px;
          position: absolute;
          bottom: 0;
          padding: 4px 8px 8px 8px;
          left: 0;
          width: 100%;
          background: #ffffff;
          border-bottom: 1px solid #f2f2f4;
          border-left: 1px solid #f2f2f4;
          border-right: 1px solid #f2f2f4;
          border-radius: 0 0 8px 8px;
          .h1 {
            font-family: HarmonyOS Sans SC, HarmonyOS Sans SC;
            font-weight: 600;
            font-size: 14px;
            color: #252525;
            line-height: 28px;
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
          }
          .text {
            font-family: HarmonyOS Sans SC, HarmonyOS Sans SC;
            font-weight: 400;
            margin-top: 5px;
            font-size: 10px;
            color: rgba(37, 37, 37, 0.5);
            line-height: 12px;
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
          }
        }

        .production {
          z-index: 2;
          background: rgba(0, 0, 0, 0.74);
          display: flex;
          justify-content: center;
          align-items: center;

          .production-content {
            img {
              display: block;
              width: 20px;
              height: 20px;
              margin: 0 auto;
              animation: spin 1s linear infinite;
            }
            @keyframes spin {
              0% {
                transform: rotate(0deg);
              }
              100% {
                transform: rotate(360deg);
              }
            }
            .production-text {
              font-family: PingFang SC, PingFang SC;
              font-weight: 400;
              font-size: 12px;
              margin-top: 10px;
              color: #ffffff;
              line-height: 14px;
              text-align: center;
            }
            .progress-text {
              font-family: PingFang SC, PingFang SC;
              font-weight: 400;
              font-size: 12px;
              margin-top: 10px;
              color: #ffffff;
              line-height: 14px;
              text-align: center;
            }
          }
        }
      }
    }
  }

  .pagination-box {
    position: sticky;
    z-index: 99;
    height: 46px;
    width: 100%;
    bottom: -20px;
    left: 0;
    background-color: #fff;
    .pagination-content {
      justify-content: center;
      display: flex;
      height: 46px;
    }
  }

  /* 批量操作相关样式 - 新增 */
  .batch-download-progress {
    padding: 15px 10px;

    .download-status {
      margin-top: 15px;
      color: #666;
      font-size: 14px;
      text-align: center;
      font-family: PingFang SC, PingFang SC;
    }

    .download-actions {
      margin-top: 20px;
      display: flex;
      justify-content: center;
      gap: 10px;
    }
  }
}

/* 选择框特定样式调整 - 确保与设计一致 */
:deep(.t-checkbox) {
  margin-right: 0;
}

:deep(.t-checkbox__input) {
  margin-right: 0;
}

/* 媒体查询 - 响应式设计 */
@media screen and (max-width: 1440px) {
  .works-content-box {
    .table-list {
      grid-template-columns: repeat(4, 1fr) !important;
    }
  }
}

@media screen and (max-width: 1200px) {
  .works-content-box {
    .table-list {
      grid-template-columns: repeat(3, 1fr) !important;
    }
  }
}

@media screen and (max-width: 768px) {
  .works-content-box {
    .table-list {
      grid-template-columns: repeat(2, 1fr) !important;
    }

    .form-box {
      flex-direction: column;
      align-items: flex-start;
      position: relative;
      top: 0;
      margin-bottom: 15px;

      .form-input {
        width: 100%;
        margin-bottom: 10px;
      }

      .batch-controls {
        width: 100%;
        margin-left: 0;
        flex-wrap: wrap;
      }
    }
  }
}
</style>
